package com.sugon.springboot.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.loadbalancer.reactive.Response;
import org.springframework.cloud.endpoint.event.RefreshEvent;
import org.springframework.cloud.gateway.event.RefreshRoutesEvent;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionWriter;
import org.springframework.cloud.gateway.support.NotFoundException;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;

@Slf4j
@Service
public class DynamicRouteService implements ApplicationEventPublisherAware {
    @Autowired
    private RouteDefinitionWriter routeDefinitionWriter;
    private ApplicationEventPublisher publisher;
    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        this.publisher=applicationEventPublisher;
    }
    /*
    * 新增路由
    * */
    public boolean add(RouteDefinition definition){
        log.info("增加路由，路由ID为："+definition.getId());
        try {
            this.routeDefinitionWriter.save(Mono.just(definition)).subscribe();
            this.publisher.publishEvent(new RefreshRoutesEvent(this));
        }catch (Exception e){
            log.error("增加路由失败");
            return false;
        }
        return true;
    }
    /*
     * 删除路由
     * */
    public Mono<ResponseEntity<Object>> delete(String id){
        log.info("删除路由规则, id为" + id);
        return this.routeDefinitionWriter.delete(Mono.just(id)).then(Mono.defer(() -> {
            return Mono.just(ResponseEntity.ok().build());
        })).onErrorResume((t) -> {
            return t instanceof NotFoundException; // 删除不存在的路由规则时不会报错？
        }, (r) -> {
            return Mono.just(ResponseEntity.notFound().build());
        });
    }
    /*
     * 修改路由
     * */
    public boolean update(RouteDefinition definition){
        log.info("更新路由规则, id为" + definition.getId());
        this.delete(definition.getId()); // 先根据id删除已有路由规则
        try {
            this.routeDefinitionWriter.save(Mono.just(definition)).subscribe(); // 写入路由配置
            this.publisher.publishEvent(new RefreshRoutesEvent(this)); // 发布路由事件
            log.info("发布路由规则, id为" + definition.getId());
        } catch (Exception e) {
            log.error("更新路由规则失败，id为" + definition.getId());
            return false;
        }
        return true;
    }
}
